/*
 * ValueSetterAction.java
 * 
 * Created on Jun 4, 2007, 12:02:40 AM
 * 
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package com.infomancers.collections.actions;

import com.infomancers.collections.Action;
import java.lang.reflect.Method;

/**
 *
 * @author aviadbd
 */
public class ValueSetterAction<T> implements Action<T>  {

    private Class<? extends T> cachedType;
    private Method method;
    private String propertyName;
    private Object value;
    
    public ValueSetterAction(Class<? extends T> cachedType, String propertyName, Object value) {
        this.method = findMethod(cachedType, propertyName);
        
        assert method != null : "Couldn't find method for property " + propertyName;
        
        this.propertyName = propertyName;
        this.cachedType = cachedType;
        this.value = value;
    }
    
    public ValueSetterAction(String propertyName, Object value) {
        this.propertyName = propertyName;
        this.value = value;
    }
    
    private Method findMethod(Class<?> type, String propertyName) {
        char[] nameChars = propertyName.toCharArray();
        nameChars[0] = Character.toUpperCase(nameChars[0]);
        
        String methodName = "set" + new String(nameChars);
        
        for (Method m : type.getMethods()) {
            if (m.getName().equals(methodName)) {
                return m;
            }
        }
        
        return null;
    }

    public void accept(T item) throws Exception {
        if (cachedType != null) {
            assert item.getClass().isAssignableFrom(cachedType) : "Wrong type, does not match cached";
            
            method.invoke(item, value);
        } else {
            findMethod(item.getClass(), propertyName).invoke(item, value);
        }
    }

}
